import { includes } from "lodash";
import React, { useState, useEffect } from "react";
import { RendererPropTypes } from "@/visualizations/prop-types";
import PlotlyChart from "./PlotlyChart";
import CustomPlotlyChart from "./CustomPlotlyChart";
import CustomThree from "./CustomThree";
import CustomTable from "./CustomTable";
import { visualizationsSettings } from "@/visualizations/visualizationsSettings";
import { axios } from "@/services/axios";
import { getCounterData } from "@/lib/functions";
import { getUrlParameterValue, getUrlParameters } from "@/lib/DateRangeParameter";

import "./renderer.less";
import CustomEcharts from "./CustomEcharts";

export default function Renderer({ options, ...props }) {
  const [refreshStartedAt, setRefreshStartedAt] = useState(props.refreshStartedAt);
  const [customCode, setCustomCode] = useState(options.customCode);
  const [plotly, setPlotly] = useState(null);

  const functionInstant = async (query, parameters, storageName, customCode, oldstr, functions) => {
    await axios.post(`api/queries/${query}/results`, { query, parameters }).then(response => {
      if ("job" in response) {
        let loop_times = 0;   
        function loop(loop_times) {
          axios.get(`api/jobs/${response.job.id}`).then(response => {
            if (!!response.job.query_result_id) {
              axios.get(`api/query_results/${response.job.query_result_id}`).then(response => {
                let rows1 = response.query_result.data.rows;
                try {
                  sessionStorage.setItem(storageName, JSON.stringify(rows1));
                } catch(e) {
                } finally {
                  let result = getCounterData(rows1, functions);
                  let mdtext = customCode;
                  if (!!functions.numberArray) {
                    mdtext = mdtext.replace('"' + oldstr +'"', result);
                  }
                  mdtext = mdtext.replace(oldstr, result);
                  setCustomCode(mdtext);  
                } 
              });
            } else {
              loop_times = loop_times + 1;
              if (loop_times < 10) {
                setTimeout(loop(loop_times), loop_times * 500);
              }
            }
          });
        }
        
        if (loop_times < 1) {
          loop_times = loop_times + 1;
          setTimeout(loop(loop_times), 500);
        }
      } else {
        let rows2 = response.query_result.data.rows;  
        try {
          sessionStorage.setItem(storageName, JSON.stringify(rows2));
        } catch(e) {
        } finally {    
          let result = getCounterData(rows2, functions);
          let mdtext = customCode;
          if (!!functions.numberArray) {
            mdtext = mdtext.replace('"' + oldstr +'"', result);
          }
          mdtext = mdtext.replace(oldstr, result);
          setCustomCode(mdtext);
        }
      }
    }).catch(error => {
      let mdtext = customCode.replace(oldstr, error);
      setCustomCode(mdtext);
    })
  }

  useEffect(() => {
    require.ensure([], function(require) {
      import(/* webpackChunkName:"plotly" */ 'plotly.js/dist/plotly.min').then(({default: _plotly}) => { 
      // const _plotly = require('plotly.js/dist/plotly.min');  //执行
        _plotly.setPlotConfig({
          modeBarButtonsToRemove: ["sendDataToCloud"],
          locale: 'zh-CN',
        });
        setPlotly(_plotly);
      });
    }, 'plotly');
  }, []); 

  if (includes(["custom", "echarts", "three", "table"], options.globalSeriesType) && visualizationsSettings.allowCustomJSVisualizations) {      
    const { data, queryId, scale, scaleX } = props;

    if (!!!refreshStartedAt && !!props.refreshStartedAt) {
      setRefreshStartedAt(props.refreshStartedAt);
    } else if (!!refreshStartedAt && !!props.refreshStartedAt) {
      if (refreshStartedAt.isBefore(props.refreshStartedAt)) {
        setRefreshStartedAt(props.refreshStartedAt);
        setCustomCode(options.customCode);
      }
    }
  
    useEffect(() => {
      let mats = /\{\{(.|\n)*?\}\}/m.exec(customCode);
      if (!mats) return;
      if (!(mats instanceof Array)) return;
  
      let oldstr = mats[0].toString();
      let objstr = oldstr.substring(1, oldstr.length-1)
      let functions;
      try {
        functions = JSON.parse(objstr);
      } catch(e) {
        let mdtext = customCode.replace(oldstr, e);
        setCustomCode(mdtext);
        return;
      }

      if (functions.hasOwnProperty("parameter")) {
        let parameterValue = getUrlParameterValue(functions.parameter)

        let mdtext = customCode.replace(oldstr, parameterValue);
        setCustomCode(mdtext);
        return;
      }
  
      if (functions.hasOwnProperty("cookie")) {
        const showPortal = window.location.search.includes("show_portal");
        let cookieStr = "";
        if (!!functions.cookie && showPortal) cookieStr = localStorage.getItem(functions.cookie);
        
        let mdtext = customCode.replace(oldstr, cookieStr);
        setCustomCode(mdtext);
        return;
      }

      if (functions.hasOwnProperty("session")) {
        let sessionStr = "";
        if (!!functions.session) {
          if (functions.session === "scale" || functions.session === "scaley" || functions.session === "scaleY") sessionStr = scale;
          if (functions.session === "scalex" || functions.session === "scaleX") sessionStr = scaleX;
          if (functions.session === "scalemin" || functions.session === "scaleMin") sessionStr = scale<scaleX ? scale : scaleX;
          if (functions.session === "scalemax" || functions.session === "scaleMax") sessionStr = scale>scaleX ? scale : scaleX;
        }
        
        let mdtext = customCode.replace(oldstr, sessionStr);
        setCustomCode(mdtext);
        return;
      }
      
      if (!functions.hasOwnProperty('query') || !functions.query || functions.query===0 || functions.query===queryId) {
        let rows = data.rows;  
        let result = getCounterData(rows, functions);
        let mdtext = customCode;
        if (!!functions.numberArray) {
          mdtext = mdtext.replace('"' + oldstr +'"', result);
        }
        mdtext = mdtext.replace(oldstr, result);
        setCustomCode(mdtext);
      } else {
        let query = functions.query;
        delete functions.query
        let parameters = functions.parameters;
        delete functions.parameters
      
        let storageName = query;
        if (parameters) {
          parameters = getUrlParameters(parameters);
          storageName = storageName + JSON.stringify(parameters);
        } 

        let rows = sessionStorage.getItem(storageName);
        if (rows) {
          let result = getCounterData(JSON.parse(rows), functions);
          let mdtext = customCode;
          if (!!functions.numberArray) {
            mdtext = mdtext.replace('"' + oldstr +'"', result);
          }
          mdtext = mdtext.replace(oldstr, result);
          setCustomCode(mdtext);
        } else {
          functionInstant(query,parameters,storageName,customCode,oldstr,functions);
        }
      }
    }, [customCode, data, queryId]);

    options.customCode = customCode;
    let mats = /\{\{(.|\n)*?\}\}/m.exec(options.customCode);
    if (mats) return null;

    if (options.globalSeriesType === "table")
      return plotly && (<CustomTable options={options} {...props} />);
    else if (options.globalSeriesType === "three")
      return plotly && (<CustomThree options={options} {...props} />);
    else if (options.globalSeriesType === "echarts")
      return plotly && (<CustomEcharts options={options} {...props} />);
    else
      return plotly && (<CustomPlotlyChart Plotly={plotly} options={options} {...props} />);
  }
  return plotly && (<PlotlyChart Plotly={plotly} options={options} {...props} />);
}

Renderer.propTypes = RendererPropTypes;
